package com.hengshan.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hengshan.common.ResultBody;
import com.hengshan.common.annotation.SystemLog;
import com.hengshan.common.enums.BusinessType;
import com.hengshan.common.utils.ExcelUtil;
import com.hengshan.common.utils.SecurityUtils;
import com.hengshan.domain.entity.Role;
import com.hengshan.domain.entity.User;
import com.hengshan.domain.vo.PageVo;
import com.hengshan.domain.vo.UserInfoVo;
import com.hengshan.service.RoleService;
import com.hengshan.service.ValidGroup;
import com.hengshan.service.impl.UserServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户表(User)表控制层
 *
 * @author muxijun
 * @since 2023-12-07 18:34:20
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/user")
public class UserController {

    private final UserServiceImpl userService;
    private final RoleService roleService;

    public static final String MODULE_NAME = "用户管理";

    /**
     * 新增用户
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.INSERT)
    @PostMapping(value = {"/add", "/register"})
    public UserInfoVo add(@Validated({ValidGroup.Insert.class}) @RequestBody User user) {
        return userService.add(user);
    }

    /**
     * 修改用户
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public UserInfoVo update(@Validated({ValidGroup.Update.class}) @RequestBody User user) {
        return userService.update(user);
    }

    /**
     * 删除用户,post方式
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.DELETE)
    @PostMapping("/delete")
    public ResultBody delete(@RequestBody Map<String, Object> map) {
        List<Long> ids = (List<Long>) map.get("id");
        Long userId = SecurityUtils.getUser().getId();
        if (ids.contains(userId)) {
            return ResultBody.fail("当前用户不能删除");
        }
        return ResultBody.success(userService.deleteByIds(ids));
    }

    /**
     * 删除用户,get方式
     * 请求格式1：curl -X GET "http://localhost:8080/system/user/delete?id=1,2,3"
     * 请求格式2：curl -X GET "http://localhost:8080/system/user/delete?id=1&id=2&id=3"
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.DELETE)
    @GetMapping("/delete")
    public ResultBody delete1(@RequestParam(name = "id") List<Long> ids) {
        Long userId = SecurityUtils.getUser().getId();
        if (ids.contains(userId)) {
            return ResultBody.fail("当前用户不能删除");
        }
        return ResultBody.success(userService.deleteByIds(ids));
    }

    /**
     * 删除用户,get方式
     * 请求格式：curl -X DELETE "http://localhost:8080/system/user/delete/1,2,3"
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.DELETE)
    @GetMapping("/delete/{id}")
    public ResultBody delete2(@PathVariable("id") List<Long> ids) {
        Long userId = SecurityUtils.getUser().getId();
        if (ids.contains(userId)) {
            return ResultBody.fail("当前用户不能删除");
        }
        return ResultBody.success(userService.deleteByIds(ids));
    }

    /**
     * 获取用户列表,post方式
     */
    @SystemLog(title = "用户管理", businessType = BusinessType.SELECT)
    @PostMapping("/list")
    public PageVo<UserInfoVo> list(@RequestBody Map<String, Object> map) {
        int pageNum = (int) map.get("pageNum");
        int pageSize = (int) map.get("pageSize");
        String username = (String) map.get("username");
        return userService.getList(pageNum, pageSize, username);
    }

    /**
     * 获取用户列表,get方式
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.SELECT)
    @GetMapping("/list")
    public PageVo<UserInfoVo> list1(@RequestParam int pageNum, @RequestParam int pageSize, @RequestParam(required = false) String username) {
        return userService.getList(pageNum, pageSize, username);
    }

    /**
     * 根据id获取详细信息
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.SELECT)
    @GetMapping(value = {"/info/{id}", "/{id}", "/"})
    public JSONObject getInfo(@PathVariable(value = "id", required = false) Long userId) {
        JSONObject res = new JSONObject();
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        List<Role> allRoles = roleService.list(wrapper.orderByAsc(Role::getOrderNum));
        res.put("roles", allRoles);
        if (Objects.nonNull(userId)) {
            UserInfoVo userInfoVo = userService.getOneById(userId);
            List<Role> roles = roleService.selectRolesByUserId(userId);
            userInfoVo.setRoles(roles);
            res.put("user", userInfoVo);
            res.put("roleIds", roles.stream().map(Role::getId).collect(Collectors.toList()));
        }
        return res;
    }

    /**
     * 重置密码
     */
    @PreAuthorize("@permission.hasPermission('system:user:resetPwd')")
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    public int resetPwd(@RequestBody User user) {
        // userService.checkUserAllowed(user);
        return userService.resetPwd(user);
    }

    /**
     * 状态修改
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.UPDATE)
    @PostMapping("/changeStatus")
    public int changeStatus(@RequestBody User user) {
        userService.checkUserAllowed(user);
        return userService.updateUserStatus(user);
    }

    /**
     * 导出用户列表
     */
    @SystemLog(title = MODULE_NAME, businessType = BusinessType.EXPORT)
    //@PreAuthorize("@permission.hasPermission('system:user:export')")
    @RequestMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream(), User.class);
        //这里设置response的动作只能在response.getOutputStream()之后，在EasyExcel的doWrite之前
        ExcelUtil.resetResponse("用户列表", response);
        List<User> userList = userService.exportExcel();
        excelWriterBuilder.autoCloseStream(false).sheet().doWrite(userList);
    }
}
